# @Time : 2020/6/24 10:58
# @Author : Fioman 
# @Phone : 13149920693
import collections
import random

"""
namedtuple 是一个对象,还有少量的属性.可以当成是一个有名的数组.它本质上还是一个对象,并且可以根据对象的一些属性进行赋值.
这样做有什么好处了? 
原来列表推导式里面是可以写双层循环的.
"""

Card = collections.namedtuple("Card", ['rank', 'suit'])  # 创建一张纸牌,rank表示扑克牌的点数,suit表示的是花色


class FrenchDeck(object):
    ranks = [str(n) for n in range(2, 11)] + list("JQKA")  # 获取扑克牌的所有点数
    suits = "spades diamonds clubs hearts".split()  # 黑桃,方块,梅花,红心

    def __init__(self):
        self._cards = [Card(rank, suit) for rank in self.ranks for suit in self.suits]  # 这种写法好屌啊.
        # 列表推导式里,可以写双层循环.真的长知识了.

    def __len__(self):
        return len(self._cards)

    def __getitem__(self, position):
        return self._cards[position]

# 黑桃a是51点.这个是先计算索引下标,然后再加上花色.索引下标*4,根据rank,牌的点数来进行的.
def spades_high(card):
    rank_value = FrenchDeck.ranks.index(card.rank)
    return rank_value * len(suit_values) + suit_values[card.suit]


if __name__ == '__main__':
    french = FrenchDeck()
    beer_card = Card("7", "diamonds")
    print("beer_card = {}".format(beer_card))
    deck = FrenchDeck()
    print("deck len = {}".format(len(deck)))

    print("第一张牌 = {}".format(deck[0]))
    print("最后一张牌 = {}".format(deck[-1]))
    # 随机的抽取一张牌
    r1 = random.choice(deck)
    print("随机牌第一张 = {}".format(r1))
    r2 = random.choice(deck)
    print("随机牌第二张 = {}".format(r2))
    r3 = random.choice(deck)
    print("随机牌第三张 = {}".format(r3))

    # 因为__getitem__方法把[]操作交给了self._card列表,所以我们的deck类自动支持切片操作.

    print("最上面的三张牌 = {}".format(deck[:3]))
    print("从12开始,每隔13张牌拿一张出来 = {}".format(deck[12::13]))

    # 牌也变成了可迭代的了
    for card in deck:
        print(card)

    # 反向迭代
    for card in reversed(deck):
        print(card)

    # 迭代通常是隐式的,譬如一个集合类型没有实现__contains__方法,那么in运算符就会按照顺序做一次迭代搜索.
    card_some = Card("Q", "hearts")
    print("card_some is in deck: {}".format(card_some in deck))

    # 如何进行排序呢?我们按照常规,用点数来判定扑克牌的大小,2最小,A最大;同时还要加上对花色的判定,黑桃最大,红桃次之,方块再次,梅花最小.
    suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0)

    for card in sorted(deck,key=spades_high):
        print(card)